package com.io.netty.groupchat;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

public class ChatServerHandler extends SimpleChannelInboundHandler<String> {

    //使用这个类来管理通道（虽然不知道为啥使用这个类）
    private static DefaultChannelGroup defaultChannelGroup
            =new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //当把ChannelHandler添加到ChannelPipeline中时被调用
    //该方法表示：一旦连接，第一个被执行（转发消息给其他客户端，服务器端并没有进行消息的打印）
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //该方法会将channelGroup中所有的channel遍历,并发送消息,我们不需要自己遍历
        defaultChannelGroup.writeAndFlush("ip为："+ctx.channel().remoteAddress()+"的好友加入聊天");
        //将当前的channel加入DefaultChannelGroup中
        defaultChannelGroup.add(ctx.channel());
    }

    //当从ChannelPipeline中移除ChannelHandler时被调用
    //该方法表示：一旦断开连接，就会执行，并自动将当前channel移出DefaultChannelGroup
    //（转发消息给其他客户端，服务器端并没有进行消息的打印）
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        defaultChannelGroup.writeAndFlush("ip为："+ctx.channel().remoteAddress()+"的好又离开聊天");
        //为了证明会自动移出DefaultChannelGroup，这里接输出一下defaultChannelGroup的size
        System.out.println("channelGroup size：" + defaultChannelGroup.size());
    }

    //Channel处于活动状态（已经连接到它的远程节点）。它现在可以接收和发送数据了
    //当通道属于活跃状态时（客户端的通道连接上服务器时，不知道跟handlerAdded方法有啥区别），
    // 提示服务器，其他客户端并不知道，只有服务器知道
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("ip为：" + ctx.channel().remoteAddress() + "的好友上线了");
    }

    //Channel没有连接到远程节点
    //当通道属不于活跃状态时（客户端的通道连接断开时，不知道跟handlerRemoved方法有啥区别），
    //当通道属于不活跃状态时，提示服务器，其他客户端并不知道，只有服务器知道
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("ip为：" + ctx.channel().remoteAddress() + "的好友离线了");
    }

    //使用这个方法来处理核心的转发业务
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        //java 1.8的特性 ***表达式
        defaultChannelGroup.forEach(channel -> {
            if (channel!=ctx.channel()){
                channel.writeAndFlush("ip为：" + ctx.channel().remoteAddress() + "的好友说："+msg);
            }else {
                channel.writeAndFlush("这是自己发的消息："+msg);
            }
        });
    }

    //当处理过程中在ChannelPipeline中有错误产生时被调用,若发生异常则关闭通道
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
